package com.ys.service.account.impl;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Map;

import com.ys.util.DateUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.fastjson.JSON;
import com.ys.dto.AddDto;
import com.ys.entity.account.TcwAdvanceAccount;
import com.ys.entity.account.TcwAdvanceAccountDetail;
import com.ys.entity.account.TcwAdvanceAccountRecharge;
import com.ys.entity.business.TbBaseInfo;
import com.ys.entity.finance.TcwPartnerBankInfo;
import com.ys.entity.flow.YspModel;
import com.ys.entity.hr.ThrOperateCompanyApply;
import com.ys.entity.sys.TsUserBankInfo;
import com.ys.entity.sys.TsUserChange;
import com.ys.entity.sys.YsCol;
import com.ys.entity.sys.YsMenu;
import com.ys.entity.sys.YsProcInst;
import com.ys.enume.finance.TcwFinancialTransactionFlowEnum;
import com.ys.enume.flow.FlowEnum;
import com.ys.enume.flow.YsProcInstEnum;
import com.ys.mapper.account.TcwAdvanceAccountDetailMapper;
import com.ys.mapper.account.TcwAdvanceAccountRechargeMapper;
import com.ys.service.account.TcwAdvanceAccountRechargeService;
import com.ys.service.business.TcwAccountDetailedForCompanyService;
import com.ys.service.finance.TcwFinancialTransactionFlowService;
import com.ys.service.flow.YspTaskService;
import com.ys.util.CheckUtil;
import com.ys.util.shiro.ShiroUtils;
import com.ys.vo.Flow;
import com.ys.vo.R;

/**
 * 预支账户充值单
 */
@Service("tcwAdvanceAccountRechargeService")
public class TcwAdvanceAccountRechargeServiceImpl implements TcwAdvanceAccountRechargeService {
	private static final Logger logger = LoggerFactory.getLogger(TcwAdvanceAccountRechargeServiceImpl.class);

	@Autowired
	private TcwAdvanceAccountRechargeMapper tcwAdvanceAccountRechargeMapper;

	@Autowired
	private TcwAdvanceAccountDetailMapper tcwAdvanceAccountDetailMapper;

	@Autowired
	private YspTaskService yspTaskService;

	@Autowired
	private TcwAccountDetailedForCompanyService tcwAccountDetailedForCompanyService;

	@Autowired
	private CheckUtil checkUtil;

	@Autowired
	private TcwFinancialTransactionFlowService tcwFinancialTransactionFlowService;

	/**
	 * 新增
	 */
	@Override
	public R add(Map<String, Object> params, Long menuId) throws Exception{
		logger.info("新增传参:"+params);
		//参数验证
		String errorBack = checkParams(params, menuId);
		if(errorBack!=null && !"".equals(errorBack)){
			return R.error(errorBack);
		}

		TcwAdvanceAccountRecharge tcwAdvanceAccountRecharge = JSON.parseObject(JSON.toJSONString(params), TcwAdvanceAccountRecharge.class);
		//验证金额
		String errorBack2 = checkParamsPrice(tcwAdvanceAccountRecharge);
		if(errorBack2!=null && !"".equals(errorBack2)){
			return R.error(errorBack2);
		}


		tcwAdvanceAccountRecharge.setStatus(1);//状态
		tcwAdvanceAccountRecharge.setEffectStock(0);//审批状态

		//获取制单人信息
		TsUserChange tsUserChange = new TsUserChange().setUserId(ShiroUtils.getUserId()).setOrderby("A.CreateTime DESC").queryFirst();
		if(tsUserChange!=null){
			tcwAdvanceAccountRecharge.setCreateChangeId(tsUserChange.getId());//制单人变更信息
		}else {
			R.error("未查询到制单人信息！");
		}
		//新增
		tcwAdvanceAccountRechargeMapper.insert(tcwAdvanceAccountRecharge);

		YsMenu ysMenu = new YsMenu().setId(menuId).queryFirst();
		if (ysMenu.getFlowModelId().longValue() != 0L) {
			YspModel yspModel = new YspModel().setId(ysMenu.getFlowModelId()).queryFirst();
			String codeModel = yspModel.getCode();
			String createUserId = ShiroUtils.getUserId();
			yspTaskService.init(codeModel, tcwAdvanceAccountRecharge.getBid(), createUserId);
		}
		//return R.ok(EditDto.closeAndReload());
		return R.ok(AddDto.gotoEdit("/web/account/tcwAdvanceAccountRecharge/toEdit?bid=" + tcwAdvanceAccountRecharge.getBid()));
	}

	/**
	 * 修改
	 */
	@Override
	public R update(Map<String, Object> params, Long menuId) throws Exception{
		logger.info("修改传参:"+params);
		//参数验证
		String errorBack = checkParams(params, menuId);
		if(errorBack!=null && !"".equals(errorBack)){
			return R.error(errorBack);
		}
		TcwAdvanceAccountRecharge tcwAdvanceAccountRecharge = JSON.parseObject(JSON.toJSONString(params), TcwAdvanceAccountRecharge.class);
		//验证金额
		String errorBack2 = checkParamsPrice(tcwAdvanceAccountRecharge);
		if(errorBack2!=null && !"".equals(errorBack2)){
			return R.error(errorBack2);
		}

		// 验证状态
		YsProcInst ysProcInst = new YsProcInst().setBid(tcwAdvanceAccountRecharge.getBid()).queryFirst();
		if (ysProcInst == null) {
			return R.error("审批数据不存在，无法编辑");
		} else if (ysProcInst.getStateFlow() != YsProcInstEnum.StateFlow.INIT.value) {
			return R.error("已流转，无法编辑");
		}
		tcwAdvanceAccountRechargeMapper.update(tcwAdvanceAccountRecharge);
		//return R.ok(AddDto.noAction());
		return R.ok();
	}


	//验证金额
	public String checkParamsPrice(TcwAdvanceAccountRecharge tcwAdvanceAccountRecharge) throws Exception {
		String errorMsg = "";
		//验证：预支账户管理 -》 账户充值余额≤预支额度
		Map<String,Object> accountInfo = new TcwAdvanceAccount()
				.addLeftJoin("(SELECT Pid, SUM(TotalPrice) AS totalPriceByRecharge FROM TCW_AdvanceAccountDetail  WHERE AdvanceTypeCode ='YZZHLX000' GROUP BY Pid) D1 on D1.Pid = A.Id AND 1=1")
				.addField("ISNULL(D1.totalPriceByRecharge, 0) AS totalPriceByRecharge")//“账户充值余额”，=充值类型之和（充值-归还）
				.setId(tcwAdvanceAccountRecharge.getAdvanceAccountId())
				.queryFirstMap();
		if(accountInfo!=null && accountInfo.get("totalPriceByRecharge")!=null){
			BigDecimal totalPriceByRecharge = new BigDecimal(accountInfo.get("totalPriceByRecharge").toString());//账户充值余额
			totalPriceByRecharge = tcwAdvanceAccountRecharge.getRechargePrice().add(totalPriceByRecharge);//加上本次充值单的充值金额
			BigDecimal advanceLimit = new BigDecimal(accountInfo.get("advanceLimit").toString());//预支额度
			if(totalPriceByRecharge.compareTo(advanceLimit)>0){
				errorMsg = "账户充值余额 不能超过 预支额度";
			}
		}else {
			errorMsg = "未查询到对应的预支账户管理信息";
		}
		return errorMsg;
	}


	//删除
	@Override
	@Transactional
	public R del(Long id) throws Exception{
		if (id == null) {
			return R.error("ID不能为空");
		}
		TcwAdvanceAccountRecharge entity = new TcwAdvanceAccountRecharge().setId(id).queryFirst();
		if (entity.getEffectStock() == FlowEnum.EffectStock.EFFECTED.value) {
			return R.error("已生效数据无法删除");
		}
		// 验证是否制单人
		String loginUserId = ShiroUtils.getUserId();
		TsUserChange tsUserChange = new TsUserChange().setId(entity.getCreateChangeId()).queryFirst();
		if (!tsUserChange.getUserId().equals(loginUserId) && !"admin".equals(loginUserId)) {
			return R.error("非制单人，无法删除");
		}
		//删除
		tcwAdvanceAccountRechargeMapper.deleteTrue(id);
		//删除流程
		yspTaskService.flowDelete(entity.getBid(), loginUserId);
		return R.ok();
	}


	/**
	 * 流转通过
	 */
	@Override
	@Transactional
	public R flowPass(Long id, String loginUserId) throws Exception {

		TcwAdvanceAccountRecharge entity = new TcwAdvanceAccountRecharge().setId(id).queryFirst();
		Flow f = yspTaskService.flowPass(entity.getBid(), loginUserId);
		if (f.getCode() == Flow.Code.FAILED.value) {
			return R.error(f.getMsg());
		} else {
			if (f.getState() == Flow.State.FINISH.value) {
				flowFinish(entity.getBid());
			}
			return R.ok();
		}
	}

	/**
	 * 流转结束
	 */
	@Override
	@Transactional
	public void flowFinish(String bid) throws Exception {

		TcwAdvanceAccountRecharge entity = new TcwAdvanceAccountRecharge().setBid(bid).queryFirst();
		YsProcInst ysProcInst = new YsProcInst().setBid(entity.getBid()).queryFirst();
		if (ysProcInst.getStateFlow() != YsProcInstEnum.StateFlow.FINISH.value) {
			return;
		}
		Date theDate = new Date();
		entity.setEffectStock(FlowEnum.EffectStock.EFFECTED.value);
		entity.setUpdateTime(theDate);

		//新增一条流水
		ThrOperateCompanyApply thrOperateCompanyApply = new ThrOperateCompanyApply().setVgsbm(entity.getVgsbm()).queryFirst();
		TcwAdvanceAccount tcwAdvanceAccount = new TcwAdvanceAccount().setId(entity.getAdvanceAccountId()).queryFirst();
		if(thrOperateCompanyApply!=null && tcwAdvanceAccount!=null){
			//新增流水
			tcwAccountDetailedForCompanyService.addTcwAccountDetailedForCompanyWithJcNoTrigger(
					entity.getVgsbm(),thrOperateCompanyApply.getVgsjc(),tcwAdvanceAccount.getCode(),tcwAdvanceAccount.getName(),
					entity.getVjylx(), BigDecimal.ZERO.subtract(entity.getRechargePrice()),entity.getCreateTime(), theDate,"预支账户充值单"+entity.getBid(),
					entity.getBid(),theDate);
		}
		
		//新增台账明细
		TcwAdvanceAccountDetail tcwAdvanceAccountDetail = new TcwAdvanceAccountDetail();
		Long userChangeId = null;
		//获取制单人信息
		TsUserChange tsUserChange = new TsUserChange().setUserId(ShiroUtils.getUserId()).setOrderby("A.CreateTime DESC").queryFirst();
		if(tsUserChange!=null){
			userChangeId = tsUserChange.getId();//制单人变更信息
			tcwAdvanceAccountDetail.setCreateChangeId(userChangeId);
		}
		tcwAdvanceAccountDetail.setPid(entity.getAdvanceAccountId());
		tcwAdvanceAccountDetail.setCreateChangeId(entity.getCreateChangeId());
		tcwAdvanceAccountDetail.setCompanyInfoVid(entity.getCompanyVid());//所属公司vid
		tcwAdvanceAccountDetail.setAdvanceTypeCode("YZZHLX000");//充值类型
		tcwAdvanceAccountDetail.setVjylx(entity.getVjylx());//交易类型名称
		tcwAdvanceAccountDetail.setDetailName("预支账户充值单"+entity.getBid());//名称
		tcwAdvanceAccountDetail.setUnitPrice(entity.getRechargePrice());//充值金额
		tcwAdvanceAccountDetail.setQuantity(new BigDecimal(1));//数量
		tcwAdvanceAccountDetail.setTotalPrice(entity.getRechargePrice());//总额
		tcwAdvanceAccountDetail.setRemark(entity.getRemark());//备注
		tcwAdvanceAccountDetail.setStatus(1);
		tcwAdvanceAccountDetail.setFromId(entity.getId());
		tcwAdvanceAccountDetail.setFromType(0);
		tcwAdvanceAccountDetail.setTransferStatus(1);
		tcwAdvanceAccountDetailMapper.insert(tcwAdvanceAccountDetail);


		//获取业务交易类型信息
		String transactionTypeStr = entity.getVjylx();
		TbBaseInfo transactionTypeItem = tcwFinancialTransactionFlowService.getTransactionType(transactionTypeStr);

		//财务交易流水
		if(transactionTypeItem!=null && transactionTypeItem.getId()!=null){
			String vyhzhmc = "";
			String vkhh = "";
			String vyhzh = "";
			if(tcwAdvanceAccount ==null){
				throw new IllegalArgumentException("未查询到对应的预支账户管理信息");
			}
			if(tcwAdvanceAccount.getAccountType()==0){
				TsUserBankInfo tsUserBankInfo = new TsUserBankInfo().setId(tcwAdvanceAccount.getUserBankInfoId()).queryFirst();
				if(tsUserBankInfo!=null && tsUserBankInfo.getVyhzhmc()!=null){
					vyhzhmc = tsUserBankInfo.getVyhzhmc();
					vkhh = tsUserBankInfo.getVkhh();
					vyhzh = tsUserBankInfo.getVyhzh();
				}else {
					throw new IllegalArgumentException("未查询到对应的银行账户名称信息");
				}
			}else {
				TcwPartnerBankInfo tcwPartnerBankInfo = new TcwPartnerBankInfo().setId(tcwAdvanceAccount.getPartnerBankInfoId()).queryFirst();
				if(tcwPartnerBankInfo!=null && tcwPartnerBankInfo.getVyhzhmc()!=null){
					vyhzhmc = tcwPartnerBankInfo.getVyhzhmc();
					vkhh = tcwPartnerBankInfo.getVkhh();
					vyhzh = tcwPartnerBankInfo.getVyhzh();
				}else {
					throw new IllegalArgumentException("未查询到对应的银行账户名称信息");
				}
			}
			R res = tcwFinancialTransactionFlowService.add(true,
					entity.getCompanyBankInfoId(), transactionTypeItem.getBid(),
					vyhzhmc,vkhh, vyhzh,
					entity.getRechargePrice().negate(),
					entity.getCreateTime(),theDate,new Date(),"预支账户充值单"+entity.getBid()+entity.getRemark(),
					TcwFinancialTransactionFlowEnum.FromType.TCW_AdvanceAccountRecharge.value,entity.getId());
			if(res.getCode().equals( R.Code.FAILED.value)){
				throw new IllegalArgumentException(res.getMsg());
			}
		}



		//修改信息
		tcwAdvanceAccountRechargeMapper.update(entity);

	}



	/**
	 * 参数验证
	 */
	public String checkParams(Map<String, Object> params, Long menuId) throws Exception {
		//获取pc字段数据
		List<YsCol> listField = new YsCol()
				.where("A.MenuId = "+menuId)
				.setOrderby("A.SortNo ASC")
				.queryList();
		//验证必填字段的非空；其他字段的长度限制、类型
		String backMsg = checkUtil.checkTableColLengthAndDataType("TCW_AdvanceAccountRecharge",listField,params,ysColItem->ysColItem.getFormEditRequired()!=null && ysColItem.getFormEditRequired() == 1);
		return backMsg;
	}



	//获取列表数据
	@Override
	@Transactional
	public Map<String,Object> getExtraParam( String bid) throws Exception{
		Map<String,Object> entity = new TcwAdvanceAccountRecharge()

				.addLeftJoin("THR_OperateCompanyApply C ON C.Vgsbm = A.Vgsbm ")
				.addField("C.Vgsjc AS vgsjc")//运营公司简称

				.addLeftJoin("TB_CompanyInfo CI ON CI.Vid = A.CompanyVid ")
				.addField("CI.Vname AS vname")//所属公司

				.addLeftJoin("TB_CompanyBankInfo CB ON CB.Id = A.CompanyBankInfoId ")
				.addField("CB.Vyhzhmc AS vyhzhmc")//付款账户名称
				.addField("CB.Vyhzh AS vyhzh")//付款账号
				.addField("CB.Vkhh AS vkhh")//付款开户行

				.addLeftJoin("TCW_AdvanceAccount AA ON AA.Id = A.AdvanceAccountId ")
				.addField("AA.Code AS code")//预支账户编码
				.addField("AA.Name AS name")//付款账户名称

				.addLeftJoin("TS_UserInfo B on  B.UserId = AA.UserId")
				.addLeftJoin("TS_OrganizationInfo O on  O.Orgid = AA.Orgid")

				.addLeftJoin("TS_UserBankInfo UB ON AA.UserBankInfoId = UB.Id AND AA.AccountType=0")
				.addLeftJoin("TCW_PartnerBankInfo PB ON AA.PartnerBankInfoId = PB.Id AND AA.AccountType=1")
				//.addField("CASE WHEN AA.AccountType=0 THEN U.Vyhzhmc ELSE P.Vyhzhmc END _ys_vyhzhmc")//银行账户名称
				//.addField("CASE WHEN AA.AccountType=0 THEN U.Vkhh ELSE P.Vkhh END _ys_vkhh")//开户行
				//.addField("CASE WHEN AA.AccountType=0 THEN U.Vyhzh ELSE P.Vyhzh END _ys_vyhzh")//银行账户编码
				.addField("O.DeptName AS deptName")//账户管理部门
				.addField("B.RoleName AS roleName")//负责人岗位
				.addField("(B.UserId + '/' + B.UserName) AS nameLinked")//账户管理负责人
				.addField("CASE WHEN AA.AccountType=0 THEN UB.Vyhzhmc ELSE PB.Vyhzhmc END vyhzhmcByAdvance")//银行账户名称
				.addField("CASE WHEN AA.AccountType=0 THEN UB.Vkhh ELSE PB.Vkhh END vkhhByAdvance")//开户行
				.addField("CASE WHEN AA.AccountType=0 THEN UB.Vyhzh ELSE PB.Vyhzh END vyhzhByAdvance")//银行账户编码
				/*
                .addLeftJoin("TS_UserBankInfo UB ON AA.UserBankInfoId = UB.Id")
                        .addLeftJoin("TS_UserInfo B on  B.UserId = UB.UserId")
                        .addField("B.DeptName AS deptName")//账户管理部门
                        .addField("B.RoleName AS roleName")//负责人岗位
                        .addField("(B.UserId + '/' + B.UserName) AS nameLinked")//账户管理负责人
                        .addField("UB.Vyhzhmc AS vyhzhmcByAdvance")//银行账户名称
                        .addField("UB.Vkhh AS vkhhByAdvance")//开户行
                        .addField("UB.Vyhzh AS vyhzhByAdvance")//银行账户编码

                 */

				//明细1
				.addLeftJoin("(SELECT Pid, SUM(TotalPrice) AS totalPriceByRecharge FROM TCW_AdvanceAccountDetail  WHERE AdvanceTypeCode ='YZZHLX000' GROUP BY Pid) D1 on D1.Pid = A.AdvanceAccountId AND 1=1")
				.addField("ISNULL(D1.totalPriceByRecharge, 0) AS totalPriceByRecharge")//账户备用金额,字段“总额”之和（预支类型为充值）


				.setBid(bid)
				.queryFirstMap();

		//获取审核时间
		YsProcInst ysProcInst = new YsProcInst().setBid(entity.get("bid").toString()).queryFirst();
		if(ysProcInst!=null && ysProcInst.getUpdateTime()!=null)entity.put("auditingTime", DateUtil.getYYYY_MM_DD_HH_mm_ss(ysProcInst.getUpdateTime()));


		return entity;
	}




}
